package com.huanuo.internetofthings.service.user;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.unicorn.framework.base.base.AbstractService;
import org.unicorn.framework.core.ResponseDto;
import org.unicorn.framework.core.SysCode;
import org.unicorn.framework.core.exception.PendingException;
import org.unicorn.framework.core.exception.UnicornRuntimeException;
import org.unicorn.framework.mybatis.config.UnicornTransactionTemplate;
import org.unicorn.framework.util.common.RandomUtils;

import com.huanuo.internetofthings.bo.impact.ImpactGroup;
import com.huanuo.internetofthings.bo.user.UserInfo;
import com.huanuo.internetofthings.bo.userCredentials.UserCredentials;
import com.huanuo.internetofthings.code.ResCode;
import com.huanuo.internetofthings.dto.user.LoginReqDto;
import com.huanuo.internetofthings.dto.user.RegisteReqDto;
import com.huanuo.internetofthings.dto.user.UserInfoRes;
import com.huanuo.internetofthings.service.impact.ImpactGroupService;

@Service
public class UserFacadeService extends AbstractService {

	@Autowired
	private UserCredentialsService userCredentialsService;

	@Autowired
	private UserInfoService userInfoService;
	
	@Autowired
	private ImpactGroupService impactGroupService;

	@Autowired
	private UnicornTransactionTemplate newTransactionTemplate;

	public ResponseDto<?> login(LoginReqDto loginReqDto) throws PendingException {
		try {
			UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginReqDto.getUserIdentity(),
					loginReqDto.getPassword());
			SecurityUtils.getSubject().login(usernamePasswordToken);
			return new ResponseDto<>();
		} catch (UnknownAccountException uae) {
			throw new PendingException(ResCode.UnknownAccount);
		} catch (IncorrectCredentialsException ice) {
			throw new PendingException(ResCode.IncorrectCredentials);
		} catch (ExcessiveAttemptsException eae) {
			throw new PendingException(ResCode.ExcessiveAttempts);
		} catch (AuthenticationException ae) {
			throw new PendingException(ResCode.UnAuthentication);
		} catch (Exception e) {
			error("系统错误", e);
			throw new PendingException(SysCode.SYS_FAIL);
		}

	}

	public ResponseDto<?> register(final RegisteReqDto registeReqDto) throws PendingException {
		return newTransactionTemplate.execute(new TransactionCallback<ResponseDto<?>>() {
			public ResponseDto<?> doInTransaction(TransactionStatus status) {
				try {
					userInfoService.addUserInfo(registeReqDto.getUserInfo());
					userCredentialsService.addUserCredentials(UserFacadeService.this.getUserCredentials(registeReqDto));
					return new ResponseDto<>();
				} catch (PendingException e) {
					status.setRollbackOnly();
					throw new UnicornRuntimeException(e.getCode(), e.getMessage());
				}
			}
		});
	}

	public ResponseDto<?> userInfo(String userIdentity) throws PendingException {
		try {
			UserInfoRes userInfoRes = new UserInfoRes();
			UserInfo userInfo = new UserInfo();
			userInfo.setUserIdentity(userIdentity);
			UserInfo queryInfo = userInfoService.getUserInfoByCondition(userInfo);
			userInfoRes.setUserInfo(queryInfo);
			ImpactGroup impactGroup=impactGroupService.getImpactGroup(ImpactGroup.builder().groupNo(queryInfo.getGroupNo()).enterpriseId(queryInfo.getEnterpriseId()).build());
			userInfoRes.setImpactGroup(impactGroup);
			return new ResponseDto<>(userInfoRes);
		} catch (PendingException e) {
			throw new UnicornRuntimeException(e.getCode(), e.getMessage());
		}
	}

	public UserCredentials getUserCredentials(RegisteReqDto registeReqDto) throws PendingException {
		UserCredentials userCredentials = new UserCredentials();
		userCredentials.setUserIdentity(registeReqDto.getUserIdentity());
		String salt = RandomUtils.getCode(6, 0);
		String password = new SimpleHash("MD5", registeReqDto.getPassword(), salt, 2).toHex();
		userCredentials.setPassword(password);
		userCredentials.setSalt(salt);
		return userCredentials;
	}
}